﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ComputerizedRehabForms
{
    public partial class BLBTestForm : Form
    {
        private bool started = false; //flag for if start button has been clicked or not
        private bool first = true; //flag to stop second call on key press
        public static int[] mouse_x = new int[17]; //holds all X coordinate values of clicks
        public static int[] mouse_y = new int[17]; //holds all Y coordinate values of clicks
        public static int[] midpoint_x = new int[17]; //holds the x value midpoint of each line
        public static int[] midpoint_y = new int[17]; //holds the y value of each line
        public static int[][] lines = new int[17][];//holds the start and end point of each line
        public static int screen_height; //height of test screen
        public static int screen_width; //width of test screen
        int count; //tracks number of mouse clicks
        Pen myPen = new Pen(Color.Gray);
        public static Point Position { get; set; }
        public BLBTestForm()
        {
            InitializeComponent();

            this.KeyPreview = true;
            this.KeyUp += new KeyEventHandler(BLBTestForm_KeyUp_1);

        }



        private void BLBTestForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void ss_button_Click(object sender, EventArgs e)
        {
            /* 
             * This method controls the start/stop function of the form 
             * Clicking start once allows tracking of subsequent clicks
             * Clicking start again will stop the test and show the results page
             */
            if (!started)
            {
                started = true;
                count = 0;
                /*
                 * Initialize all values of mouse click coordiantes to -50
                 * This is done so that "empty" mouse clicks are drawn off screen in Results form
                 */
                for (int i = 0; i < 17; i++)
                {
                    mouse_x[i] = -50;
                    mouse_y[i] = -50;
                }

                /*
                 * We need to draw all of the lines in black here
                 * Before this section of code is ran, the lines should be drawn in grey
                 * I am not sure if it is easier to redraw the lines here, or if we can just change their color
                 */


                Graphics g;

                g = this.CreateGraphics();
                myPen.Width = 3;
                myPen.Color = System.Drawing.Color.Black;

                LineDraw(g);

            }
            else
            {
                /*
                 * Stop button clicked
                 * Hide Test form and go to Results form
                 */
                started = false;
                first = true;
                DataManager.hideBLBTest();
                DataManager.showBLBResults();
            }
        }

        private void back_button_Click(object sender, EventArgs e)
        {
            started = false;
            first = true;
            DataManager.hideBLBTest();
            DataManager.showLogin();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            /*
             * This method handles the line drawing for the test 
             * Lines are drawn grayed out initially, and will be redrawn black after the start button is clicked
             * Midpoint of each line is calculated and stored in array for later use
             */
            base.OnPaint(e);
            Graphics g;

            g = e.Graphics;

            myPen.Width = 3;
            myPen.Color = System.Drawing.Color.Gray;
            

            screen_width = this.Width;
            screen_height = this.Height;

            /*
             * Initialize all line values here
             * [N][0] = starting X coordinate
             * [N][1] = ending X coordinate
             * [N][2] = start and end Y coordinate
             * [N][3] = length of line
             */
            lines[0] = new int[4];
            lines[0][0] = 300;
            lines[0][1] = screen_width - 300;
            lines[0][2] = (3 * screen_height) / 40;
            lines[0][3] = screen_width - 600;

            lines[1] = new int[4];
            lines[1][0] = 0;
            lines[1][1] = screen_width - 500;
            lines[1][2] = (5 * screen_height) / 40;
            lines[1][3] = screen_width - 500;

            lines[2] = new int[4];
            lines[2][0] = 750;
            lines[2][1] = screen_width - 100;
            lines[2][2] = (7 * screen_height) / 40;
            lines[2][3] = screen_width - 850;

            lines[3] = new int[4];
            lines[3][0] = 400;
            lines[3][1] = screen_width - 400;
            lines[3][2] = (9 * screen_height) / 40;
            lines[3][3] = screen_width - 800;

            lines[4] = new int[4];
            lines[4][0] = 25;
            lines[4][1] = screen_width / 2;
            lines[4][2] = (11 * screen_height) / 40;
            lines[4][3] = (screen_width / 2) - 25;

            lines[5] = new int[4];
            lines[5][0] = 350;
            lines[5][1] = screen_width;
            lines[5][2] = (13 * screen_height) / 40;
            lines[5][3] = screen_width - 350;

            lines[6] = new int[4];
            lines[6][0] = 300;
            lines[6][1] = screen_width - 250;
            lines[6][2] = (15 * screen_height) / 40;
            lines[6][3] = screen_width - 550;

            lines[7] = new int[4];
            lines[7][0] = 50;
            lines[7][1] = screen_width - 800;
            lines[7][2] = (17 * screen_height) / 40;
            lines[7][3] = screen_width - 850;

            lines[8] = new int[4];
            lines[8][0] = 200;
            lines[8][1] = screen_width - 250;
            lines[8][2] = (19 * screen_height) / 40;
            lines[8][3] = screen_width - 450;

            lines[9] = new int[4];
            lines[9][0] = 450;
            lines[9][1] = screen_width - 100;
            lines[9][2] = (21 * screen_height) / 40;
            lines[9][3] = screen_width - 550;

            lines[10] = new int[4];
            lines[10][0] = 300;
            lines[10][1] = screen_width - 350;
            lines[10][2] = (23 * screen_height) / 40;
            lines[10][3] = screen_width - 650;

            lines[11] = new int[4];
            lines[11][0] = 0;
            lines[11][1] = screen_width - 500;
            lines[11][2] = (25 * screen_height) / 40;
            lines[11][3] = screen_width - 500;

            lines[12] = new int[4];
            lines[12][0] = 650;
            lines[12][1] = screen_width - 50;
            lines[12][2] = (27 * screen_height) / 40;
            lines[12][3] = screen_width - 700;

            lines[13] = new int[4];
            lines[13][0] = 200;
            lines[13][1] = screen_width - 200;
            lines[13][2] = (29 * screen_height) / 40;
            lines[13][3] = screen_width - 400;

            lines[14] = new int[4];
            lines[14][0] = 150;
            lines[14][1] = screen_width - 650;
            lines[14][2] = (31 * screen_height) / 40;
            lines[14][3] = screen_width - 800;

            lines[15] = new int[4];
            lines[15][0] = 600;
            lines[15][1] = screen_width - 100;
            lines[15][2] = (33 * screen_height) / 40;
            lines[15][3] = screen_width - 700;

            lines[16] = new int[4];
            lines[16][0] = screen_width / 3;
            lines[16][1] = 2 * screen_width / 3;
            lines[16][2] = (35 * screen_height) / 40;
            lines[16][3] = screen_width / 3;

            /*
             * 17 lines are drawn, based on the example given by client
             * The X value midpoint of each line is found by (X2 + X1)/2
             * The Y value of the midpoint is the Y value of the line
             * This value is saved in an array for use in the Results page             
             */
            
            midpoint_x[0] = screen_width / 2;
            midpoint_y[0] = (3 * screen_height) / 40; 

            
            midpoint_x[1] = (screen_width - 500) / 2;
            midpoint_y[1] = (5 * screen_height) / 40;

            
            midpoint_x[2] = (screen_width + 650) / 2;
            midpoint_y[2] = (7 * screen_height) / 40;

            
            midpoint_x[3] = screen_width / 2;
            midpoint_y[3] = (9 * screen_height) / 40;

            
            midpoint_x[4] = ((screen_width / 2) + 25) / 2;
            midpoint_y[4] = (11 * screen_height) / 40;

            
            midpoint_x[5] = (screen_width + 350) / 2;
            midpoint_y[5] = (13 * screen_height) / 40;

            
            midpoint_x[6] = (screen_width + 50) / 2;
            midpoint_y[6] = (15 * screen_height) / 40;

            
            midpoint_x[7] = (screen_width - 750) / 2;
            midpoint_y[7] = (17 * screen_height) / 40;

            
            midpoint_x[8] = (screen_width - 50) / 2;
            midpoint_y[8] = (19 * screen_height) / 40;

            
            midpoint_x[9] = (screen_width + 350) / 2;
            midpoint_y[9] = (21 * screen_height) / 40;

            
            midpoint_x[10] = (screen_width - 50) / 2;
            midpoint_y[10] = (23 * screen_height) / 40;

            
            midpoint_x[11] = (screen_width - 500) / 2;
            midpoint_y[11] = (25 * screen_height) / 40;

            
            midpoint_x[12] = (screen_width + 600) / 2;
            midpoint_y[12] = (27 * screen_height) / 40;

            
            midpoint_x[13] = screen_width / 2;
            midpoint_y[13] = (29 * screen_height) / 40;

           
            midpoint_x[14] = (screen_width - 500) / 2;
            midpoint_y[14] = (31 * screen_height) / 40;

            
            midpoint_x[15] = (screen_width + 500) / 2;
            midpoint_y[15] = (33 * screen_height) / 40;

            
            midpoint_x[16] = (screen_width / 3 + (2 * screen_width / 3)) / 2;
            midpoint_y[16] = (35 * screen_height) / 40;



            LineDraw(g);//draws the lines

        }

        private void BLBTestForm_Click(object sender, EventArgs e)
        {
            /*
             * This method handles any mouse clicks on screen
             * The position of click is recorded, and a red X is drawn at that location
             * 
             */
            if (started)
            {
                /*If the start button has been clicked, record the coordinates of each click*/
                this.Cursor = new Cursor(Cursor.Current.Handle);

                Graphics g;
                g = this.CreateGraphics();
                myPen.Color = System.Drawing.Color.Red;
                if (count > 16)
                {
                    count = 16;//Any clicks after the first 17 just change the last coordinate

                    myPen.Color = System.Drawing.Color.White; // erase last X by drawing over it in white
                    g.DrawLine(myPen, BLBTestForm.mouse_x[count] - 10, BLBTestForm.mouse_y[count] - 10, BLBTestForm.mouse_x[count] + 10, BLBTestForm.mouse_y[count] + 10);
                    g.DrawLine(myPen, BLBTestForm.mouse_x[count] - 10, BLBTestForm.mouse_y[count] + 10, BLBTestForm.mouse_x[count] + 10, BLBTestForm.mouse_y[count] - 10);

                    myPen.Color = System.Drawing.Color.Black;
                    LineDraw(g);// redraw lines to remove holes from erasing X

                    myPen.Color = System.Drawing.Color.Red;
                }
                /*
                 * We need to change this so that each new y coordinate is compared to each other y coordinate
                 * If they are within some certain threshold, like 15 pixels, then replace the old pair of coordinates with the new pair
                 * 
                 * We also need to check each new y coordinate to see if it is within a certain threshold of the test lines
                 * If it is, change the y coordinate to be on that line, and leave the x coordiante alone
                 */

                mouse_x[count] = PointToClient(Cursor.Position).X;
                mouse_y[count] = PointToClient(Cursor.Position).Y;

                AutoCorrect();
                count++;
                X_Draw(g);
               
            }

        }

        /*
         * This method is called whenever the test lines need to be drawn
         * The color of the lines should be specified before the method is called 
         */
        private void LineDraw(Graphics g)
        {


            for (int i = 0; i < 17; i++)
            {

                g.DrawLine(myPen, lines[i][0], lines[i][2], lines[i][1], lines[i][2]);
            }


        }

        /*
         *This method is used to draw the X's after each mouse click
         *Every click in the array is drawn every time this method is called
         *This shoud allow users to manually undo multiple clicks, then have subsequent clicks drawn to the screen correctly
         */
        private void X_Draw(Graphics g)
        {
            for (int i = 0; i < count; i++ )
            {
                g.DrawLine(myPen, BLBTestForm.mouse_x[i] - 10, BLBTestForm.mouse_y[i] - 10, BLBTestForm.mouse_x[i] + 10, BLBTestForm.mouse_y[i] + 10);
                g.DrawLine(myPen, BLBTestForm.mouse_x[i] - 10, BLBTestForm.mouse_y[i] + 10, BLBTestForm.mouse_x[i] + 10, BLBTestForm.mouse_y[i] - 10);
            }
        }

        private void BLBTestForm_KeyUp_1(object sender, KeyEventArgs e)
        {

            /*
             * This method handles the manual Undo key
             * When the backspace is pressed, the last mouse click is erased
             * First the count is reduced by one, to the previous click
             * Then the drawn X is erased, and all of the lines redrawn to remove any holes in them
             * The coordinates for that click are then reset to the initial values
             * 
             * NOTE: For some reason this method is called twice on a single key press
             * I am adding a flag to prevent the second call, since I am too lazy to figure out why it is happening 
             */
            if (e.KeyCode == Keys.Back)
            {

                if (count > 0 && first)
                {


                    count--;// reduce count to last saved click

                    Graphics g = this.CreateGraphics();

                    myPen.Color = System.Drawing.Color.White; // erase last X by drawing over it in white
                    g.DrawLine(myPen, BLBTestForm.mouse_x[count] - 10, BLBTestForm.mouse_y[count] - 10, BLBTestForm.mouse_x[count] + 10, BLBTestForm.mouse_y[count] + 10);
                    g.DrawLine(myPen, BLBTestForm.mouse_x[count] - 10, BLBTestForm.mouse_y[count] + 10, BLBTestForm.mouse_x[count] + 10, BLBTestForm.mouse_y[count] - 10);

                    myPen.Color = System.Drawing.Color.Black;
                    LineDraw(g);// since we draw the Xs in white, it erases part of the line; this fixes that
                    
                    //reset the last coordinates to their initial values
                    mouse_x[count] = -50;
                    mouse_y[count] = -50;
                    first = false;// set flag so that second call does not go through

                    //redarw all of the Xs so that they lay on top of the lines instead of under
                    myPen.Color = System.Drawing.Color.Red;
                    X_Draw(g);

                }
                else first = true;// on second call, reset flag so first new key press goes through     
                
            }

        }


        private void AutoCorrect()
        {
            /*
             * This method will automatically reposition mouse clicks based on certain criteria
             * First, if a click is within 10 pixels of a test line on the Y axis, the click is moved to the line, with the same X coordinate
             * Next, if the user clicks on a line that has already been clicked on, the old click is erased and updated with the new click
             */

            /*
             * this loop will compare the Y value of the last click to the Y values of each line
             * If they are within 10 pixels in either direction the Y value is changed to that of the line
             */
            for (int i = 3; i <= 33; i = i+2)
            {
                int distance = mouse_y[count] - ( (i * screen_height) / 40 );//pix3els between line and click
                if((-10 <= distance) && (distance <= 10)){
                    mouse_y[count] = (i * screen_height) / 40 ; //if -10 < distance < 10 move click to line
                    i = 100;//found a match, break out of loop
                }
            }

            /*
             * After normalizing clicks to lines, check to see if any other clicks are on that line
             * If there is a match, erase the old click and update its coordinates with the new click
             */


            Graphics g = this.CreateGraphics();
            

            for (int i = 0; i < count; i++)
            {
                if (mouse_y[count] == mouse_y[i])
                {
                    myPen.Color = System.Drawing.Color.White; // erase matching X by drawing over it in white
                    g.DrawLine(myPen, BLBTestForm.mouse_x[i] - 10, BLBTestForm.mouse_y[i] - 10, BLBTestForm.mouse_x[i] + 10, BLBTestForm.mouse_y[i] + 10);
                    g.DrawLine(myPen, BLBTestForm.mouse_x[i] - 10, BLBTestForm.mouse_y[i] + 10, BLBTestForm.mouse_x[i] + 10, BLBTestForm.mouse_y[i] - 10);

                    myPen.Color = System.Drawing.Color.Black;
                    LineDraw(g);// redraw lines to remove holes from erasing X

                    mouse_x[i] = mouse_x[count];// change X value to new location, Y values already the same

                    count--;// since this click replaces another, count should not increase
                    i = 100;// break out of loop
                }
                
            }
            myPen.Color = System.Drawing.Color.Red;

        }

    }
}